import { ArrayMethods } from "./arr"
import Dep from './dep'
export function observer(data) {
  if(typeof data != 'object' || data == null) {
    return data
  }
  return new Observer(data)
}

class Observer{
  constructor(value) {
    // 给 value 定义一个属性
    Object.defineProperty(value, "__ob__", {
      enumerable: false,
      value: this
    })
    if(Array.isArray(value)) {
      value.__proto__ = ArrayMethods
      this.observeArray(value)
    } else {
      this.walk(value) // 遍历
    }
  }
  walk(data) {
    let keys = Object.keys(data)
    for(let i = 0; i < keys.length; i++) {
      let key = keys[i]
      let value = data[key]
      defineReactive(data, key, value)
    }
  }
  observeArray(value) {
    for(let i = 0; i < value.length; i++) {
      observer(value[i])
    }
  }
}

function defineReactive(data, key, value) {
  observer(value)
  Object.defineProperty(data, key, {
    get() {
      return value
    },
    set(newValue) {
      if(newValue == value) return;
      observer(newValue)
      value = newValue
    }
  })
}